package com.ray.exercise.utils;

import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.Sha1Hash;
import org.apache.shiro.util.StringUtils;

/**
 * @author reny
 * created at 2024/6/11 10:21
 **/
public class DigestsUtils {

    private static final RandomNumberGenerator generator;

    private static final int DEFAULT_SALT_LENGTH = 16;

    private static final int DEFAULT_HASH_ITERATIONS = 4;

    static {
        generator = new SecureRandomNumberGenerator();
    }

    public static String md5(Object source) {
        return digest(Md5Hash.ALGORITHM_NAME, source);
    }

    public static String md5(Object source, String salt) {
        return digest(Md5Hash.ALGORITHM_NAME, source, salt);
    }

    public static String md5(Object source, String salt, int hashIterations) {
        return digest(Md5Hash.ALGORITHM_NAME, source, salt, hashIterations);
    }

    public static String sha1(Object source) {
        return digest(Sha1Hash.ALGORITHM_NAME, source);
    }

    public static String sha1(Object source, String salt) {
        return digest(Sha1Hash.ALGORITHM_NAME, source, salt);
    }

    public static String sha1(Object source, String salt, int hashIterations) {
        return digest(Sha1Hash.ALGORITHM_NAME, source, salt, hashIterations);
    }

    public static String digest(String algorithmName, Object source) {
        return digest(algorithmName, source, null);
    }

    public static String digest(String algorithmName, Object source, String salt) {
        return digest(algorithmName, source, salt, DEFAULT_HASH_ITERATIONS);
    }

    public static String digest(String algorithmName, Object source, String salt, int hashIterations) {
        if (!StringUtils.hasText(salt)) {
            salt = genRandomSalt();
        }
        if (hashIterations <= 0) {
            hashIterations = DEFAULT_HASH_ITERATIONS;
        }
        String defaultHash = new Sha1Hash(source, salt, hashIterations).toString();
        if (Md5Hash.ALGORITHM_NAME.equals(algorithmName)) {
            return new Md5Hash(source, salt, hashIterations).toString();
        }
        return defaultHash;
    }

    public static String genRandomSalt(int numBytes) {
        if (numBytes <= 0) {
            numBytes = DigestsUtils.DEFAULT_SALT_LENGTH;
        }
        return generator.nextBytes(numBytes).toString();
    }

    public static String genRandomSalt() {
        return genRandomSalt(DigestsUtils.DEFAULT_SALT_LENGTH);
    }

}
